package com.smasher.net.http

import com.google.gson.JsonParseException
import com.smasher.net.entity.BaseLoong
import org.apache.http.conn.ConnectTimeoutException
import org.json.JSONException
import retrofit2.HttpException
import java.io.IOException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException


fun Throwable.handleExceptionToBaseData(): BaseLoong {
    return ApiException.build(exception = this).toResponse()
}

class ApiException(
    val httpCode: Int, val httpMessage: String
) {


    companion object {

        const val TAG = "ApiException"

        // 网络状态码
        private const val CODE_NET_ERROR = 4000
        private const val CODE_TIMEOUT = 4080
        private const val CODE_JSON_PARSE_ERROR = 4010
        private const val CODE_SERVER_ERROR = 5000

        // 业务状态码
        const val CODE_AUTH_INVALID = 401

        @JvmStatic
        fun build(exception: Throwable): ApiException {
            return when (exception) {
                is HttpException -> parseHttpException(exception)
                is UnknownHostException ->
                    ApiException(CODE_NET_ERROR, "域名连接失败，请检查后再试")

                is ConnectTimeoutException ->
                    ApiException(CODE_TIMEOUT, "请求超时，请稍后再试")

                is ConnectException ->
                    ApiException(CODE_NET_ERROR, "网络连接失败，请检查后再试")

                is SocketTimeoutException ->
                    ApiException(CODE_TIMEOUT, "请求超时，请稍后再试")

                is IOException ->
                    ApiException(CODE_NET_ERROR, "网络异常(${exception.message})")

                is JsonParseException ->
                    ApiException(
                        CODE_JSON_PARSE_ERROR,
                        exception.message ?: "未知错误"
                    )

                is JSONException ->
                    ApiException(
                        CODE_JSON_PARSE_ERROR,
                        exception.message ?: "未知错误"
                    )

                else -> ApiException(CODE_SERVER_ERROR, "系统错误(${exception.message})")
            }
        }

        private fun parseHttpException(exception: HttpException): ApiException {
            val code = exception.code()
            val message = exception.message()
            return when {
                code == 401 -> {
                    ApiException(CODE_AUTH_INVALID, "登录过期，请重新登录")
                }

                code == 403 -> {
                    ApiException(CODE_AUTH_INVALID, "没有权限")
                }

                code == 404 -> {
                    ApiException(CODE_SERVER_ERROR, "请求地址错误")
                }

                code in 405 until 500 -> {
                    ApiException(CODE_SERVER_ERROR, "请求错误")
                }

                code >= 500 -> {
                    ApiException(CODE_SERVER_ERROR, "服务器错误")
                }

                else -> {
                    ApiException(900, exception.message ?: message)
                }
            }

        }
    }

    fun toResponse(): BaseLoong {
        return BaseLoong(
            code = this@ApiException.httpCode,
            message = this@ApiException.httpMessage
        )
    }

}